package org.maiyoframework.core.common;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import javax.persistence.Entity;

@SuppressWarnings({"unchecked","rawtypes"})
public class BeanUtils {
	
	/**
	 * 获得指定类(clazz)的父类泛型参数的实际类型
	 * 即获得UserDao extends BaseDao<User>中的User
	 * 
	 * @param clazz
	 *            clazz对象
	 * @param index
	 *            泛型参数索引
	 *            
	 * @return 泛型参数的实际类型
	 */
	public static Class getGenericClass(Class clazz, int index) {
		// 得到泛型父类,包含泛型参数信息,如:Class<User>
		Type genericClassType = clazz.getGenericSuperclass();
		// 所有泛型必须实现ParameterizedType接口，如没实现则不是泛型，直接返回Object.class
		if (!(genericClassType instanceof ParameterizedType)) {
			return Object.class;
		}
		// 得到泛型实际参数中对应的Class,如Class<User>中的User,参数可为多个，所以定义为数组
		Type params[] = ((ParameterizedType) genericClassType)
				.getActualTypeArguments();
		if (index >= params.length || index < 0) {
			throw new RuntimeException("Param Index Out Of Range");
		}
		if (!(params[index] instanceof Class)) {
			return Object.class;
		}
		return (Class) params[index];

	}

	/**
	 * 获得指定类(clazz)的父类泛型参数的实际类型
	 * 即获得UserDao extends BaseDao<User>中的User
	 * 
	 * @param clazz
	 *            clazz对象
	 *            
	 * @return 泛型参数的实际类型
	 */
	public static Class getGenericClass(Class clazz) {
		return getGenericClass(clazz, 0);
	}

	/**
	 * 获得Class对象的类名称
	 * 
	 * @param entityClass
	 *            需要获得名称的Class对象
	 *            
	 * @return 类名称
	 */
	public static String getEntityClassName(Class entityClass) {
		// 取得类的名称，如public class User,得到的名称则为User
		String entityClassName = entityClass.getSimpleName();
		// 取得Jpa注解自定义名称，如@Entity(name="UserExt")
		Entity entity = (Entity) entityClass.getAnnotation(Entity.class);
		// 判断类有无注解自定义名称，如果有则类的名称则为@Entity中定义的名称
		if (entity.name() != null && !"".equals(entity.name()))
			entityClassName = entity.name();
		return entityClassName;
	}
	
	/**
	 * 通过属性名获取Get方法名
	 * 
	 * @param propertyName
	 *            属性名
	 * @return Get方法名
	 */
	public static String catchGetMethodByProperty(String propertyName) {
		return "get" + propertyName.substring(0, 1).toUpperCase()
				+ propertyName.substring(1);
	}
	
	/**
	 * 通过属性名获取Set方法名
	 * 
	 * @param propertyName
	 *            属性名
	 * @return Set方法名
	 */
	public static String catchSetMethodByProperty(String propertyName) {
		return "set" + propertyName.substring(0, 1).toUpperCase()
				+ propertyName.substring(1);
	}

}
